<?php

namespace app\api\controller\order;

use app\api\model\common\CoinModel;
use app\api\model\mine\MiningMachineModel;
use app\api\model\order\OrderEarningModel;
use app\api\model\order\OrderMiningModel;
use app\api\model\user\UserAssetsLogModel;
use app\api\model\user\UserAssetsModel;
use app\api\request\mine\MiningRequest;
use app\api\request\order\OrderMiningRequest;
use app\common\controller\Api;
use think\Exception;
use think\Loader;

class OrderMining extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = ['*'];

    /**
     * Notes: 购买wawaji
     * User: 浪子膏
     * Date: 2023/10/31 16:20
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function create()
    {
        $params = request()->post();
        $validate = Loader::validate(OrderMiningRequest::class);
        if (!$validate->scene('create')->check($params)) $this->error($validate->getError());

        $miningMachineModel = new MiningMachineModel();
        $info = $miningMachineModel->where('id', $params['mining_id'])->find();
        if (empty($info)) {
            $this->error(__('That information no longer exists'));
        }
        if ($info['surplus_stock'] < $params['number']) {
            $this->error(__('The inventory of mining machines is insufficient'));
        }
        $orderMiningModel = new OrderMiningModel();
        $coinModel = new CoinModel();
        $coinInfo = $coinModel->where('id', $info['coin_id'])->find();
        if (empty($coinInfo)) {
            $this->error(__('Currency information is abnormal'));
        }
        $userAssetsModel = new UserAssetsModel();
        $assetsInfo = $userAssetsModel->where('user_id', $this->auth->id)->find();
        if (empty($assetsInfo)) {
            $this->error(__('Abnormal user asset information'));
        }
        if ($info['price'] > 0) {
            $amount = $info['price'] * $params['number'];
            if ($assetsInfo['usdt'] < $amount) {
                $this->error(__('Your balance is insufficient'));
            }
        } else {
            if ($params['number'] != 1) {
                $this->error(__('You can only buy one free miner'));
            }
            if ($orderMiningModel->where(['coin_id' => $coinInfo['id'],
                'user_id' => $this->auth->id, 'price' => 0])->count()) {
                $this->error(__('Free miner can only buy one per person'));
            }
        }

        $data = [];
        for ($i = 0; $i < $params['number']; $i++) {
            $order_no = order_no('MI');
            $data[] = [
                'order_no' => $order_no,
                'user_id' => $this->auth->id,
                'coin_id' => $info['coin_id'],
                'mining_id' => $info['id'],
                'name' => $info['name'],
                'computing_power' => $info['computing_power'],
                'electricity_bill' => $info['electricity_bill'],
                'power' => $info['power'],
                'price' => $info['price'],
                'period' => $info['period'],
                'status' => OrderMiningModel::STATUS_PAY,
                'model_number' => '蚂蚁矿机' . $this->randomChars(1) . rand(1, 100) . 'PRO',
                'ip' => '162.254.' . rand(1, 255) . '.' . rand(1, 255),
            ];
        }
        if (count($data) <= 0) {
            $this->error(__('That information no longer exists'));
        }
        $orderMiningModel->startTrans();
        try {
            if ($info['price'] > 0) {
                //扣除余额
                $assetsInfo->usdt = $assetsInfo->usdt - $amount;
                $assetsInfo->save();
                //写入日志
                $userAssetsLogModel = new UserAssetsLogModel();
                $userAssetsLogModel->createLog('usdt', $this->auth->id, $amount, UserAssetsLogModel::TYPE_MINING, 2, $order_no);
            }

            //创建订单
            $orderMiningModel->saveAll($data);
            //扣除矿机 剩余数量
            $info->surplus_stock = $info->surplus_stock - $params['number'];
            $info->save();

            $orderMiningModel->commit();
        } catch (Exception $exception) {
            $orderMiningModel->rollback();
            $this->error($exception->getMessage());
        }

        $this->success();

    }


    /**
     * Notes: 矿机中心
     * User: 浪子膏
     * Date: 2023/11/2 11:00
     * @throws \think\exception\DbException
     */
    public function machineCenter()
    {
        $params = request()->post();
        $validate = Loader::validate(OrderMiningRequest::class);
        if (!$validate->scene('machineCenter')->check($params)) $this->error($validate->getError());

        $orderMiningModel = new OrderMiningModel();
        $wh = [];
        if (!empty($params['coin_id'])) {
            $wh['coin_id'] = ['eq', $params['coin_id']];
        }
        $wh['user_id'] = ['eq', $this->auth->id];
        $list = $orderMiningModel->where($wh)->field('order_no,user_id,coin_id,mining_id,name,computing_power,price,
        executed_day,period,status,model_number,ip')->order('create_time desc')->paginate($params['page_size'] ?? 15)->each(function ($item) {
            $item['computing_power'] = floatval($item['computing_power']);
            $item['price'] = floatval($item['price']);
        });

        $this->dataOk($list);
    }


    function randomChars($length)
    {
        $returnStr = '';
        $pattern = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        for ($i = 0; $i < $length; $i++) {
            $returnStr .= $pattern[mt_rand(0, strlen($pattern) - 1)]; //生成php随机数
        }
        return $returnStr;
    }


    /**
     * Notes: 矿机详情
     * User: 浪子膏
     * Date: 2023/11/2 11:16
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function info()
    {
        $params = request()->post();
        $validate = Loader::validate(OrderMiningRequest::class);
        if (!$validate->scene('info')->check($params)) $this->error($validate->getError());
        $orderMiningModel = new OrderMiningModel();

        $wh['order_no'] = ['eq', $params['order_no']];
        $wh['user_id'] = ['eq', $this->auth->id];
        $info = $orderMiningModel->where($wh)->find();
        if (empty($info)) {
            $this->error(__('That information no longer exists'));
        }
        $info['computing_power'] = floatval($info['computing_power']);
        $info['electricity_bill'] = floatval($info['electricity_bill']);
        $info['power'] = floatval($info['power']);
        $info['price'] = floatval($info['price']);
        $orderEarningModel = new OrderEarningModel();
        $info['coin'] = CoinModel::where('id', $info['coin_id'])->field('id,coin_type,coin_price_usd')->find();
        $info['child'] = $orderEarningModel->where('order_no', $info['order_no'])->order('create_time desc')->select();

        $this->dataOk($info);
    }
}